﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Cashier.usercontrols;
using Cashier_Service;
using Cashier_Model;
using System.Collections;
using Cashier.utils;
using Cashier_Utils;
using Cashier_Interface;
using Cashier.member;
using Cashier.prints;
using System.Text.RegularExpressions;
using System.Drawing.Printing;

namespace Cashier.pos
{
    public partial class PosForm : FormExt, IGoodsNorm, IReloadData
    {
        private MainForm mainform;
        private static PosForm posform;
        private GoodsService goodsService;
        private Hashtable shipmentTable; //存储挂单信息
        private MemberService memberService;
        private BillShipmentService shipmentService;
        private Member member;

        private DiscountType discountType = DiscountType.Discount; //总价额外优惠方式
        private Decimal discount = 0M; //总价额外优惠数量
        private Decimal discountAmount = 0M; //总价额外优惠金额
        private Decimal shipmentTotal_first = 0M; //最初出货单总金额

        private PosBillPrintDoc posBillPrintDoc; //存储打印对象

        /// <summary>
        /// 私有构造函数
        /// </summary>
        /// <param name="mainform"></param>
        private PosForm(MainForm mainform)
        {
            InitializeComponent();            
            this.mainform = mainform;
            goodsService = new GoodsService();
            this.GeneratorDataGridViewColumns();
            shipmentTable = new Hashtable();
            this.memberService = new MemberService();
            this.shipmentService = new BillShipmentService();

            textbox_shipmentdate.Text = DateTime.Now.ToString("yyyy-MM-dd");
            textbox_shipmentuser.Text = mainform.Admin.Name;
            label_shipmentno.Text = this.GetShipmentNo();
        }

        /// <summary>
        /// 获取PosForm实例
        /// </summary>
        /// <param name="mainform"></param>
        /// <returns></returns>
        public static PosForm GetPosForm(MainForm mainform)
        {
            if (posform == null)
                posform = new PosForm(mainform);
            return posform;
        }

        /// <summary>
        /// 获取出货单NO
        /// </summary>
        /// <returns></returns>
        private String GetShipmentNo()
        {
            return ToolsUtil.GenerateShipmentNO();
        }

        /// <summary>
        /// 会员名称
        /// </summary>
        public String Membername
        {
            get { return this.textbox_membername.Text.Trim(); }
        }

        /// <summary>
        /// 恢复收帐模式
        /// </summary>
        private void RestorePosForm()
        {
            this.discountType = DiscountType.NO;
            this.discountAmount = 0M;

            textbox_shipmentdate.Text = DateTime.Now.ToString("yyyy-MM-dd");
            label_shipmentno.Text = this.GetShipmentNo();

            dataGridView1.Rows.Clear();
            textBox_barcode.Text = String.Empty;
            textbox_memberno.Text = String.Empty;
            textbox_membername.Text = String.Empty;
            textBox_numbers.Text = "1";
            textBox_stock.Text = "0";
            label_totalold.Text = "0.00";
            label_totaldiscount.Text = "0.00";
            label_totalnew.Text = "0.00";
        }

        #region DataGridView 初始化

        /// <summary>
        /// 生成列
        /// </summary>
        protected void GeneratorDataGridViewColumns()
        {
            this.dataGridView1.AutoGenerateColumns = false;
            this.dataGridView1.Columns.Clear();
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("barcode", null, true, 0, null, null, false, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("goods_name", "商品名称", true, 30, ActKey.LEFT, ActKey.LEFT, true, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("category_name", "商品分类", true, 10, ActKey.LEFT, ActKey.LEFT, true, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("goods_norm", "商品规格", true, 10, ActKey.LEFT, ActKey.LEFT, true, false));            
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("price_sale", "商品单价", true, 10, ActKey.RIGHT, ActKey.RIGHT, true, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("discount", "折扣率", true, 10, ActKey.RIGHT, ActKey.RIGHT, true, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("price_disc", "出货单价", true, 10, ActKey.RIGHT, ActKey.RIGHT, true, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("numbers", "出货数量", true, 10, ActKey.RIGHT, ActKey.RIGHT, true, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("total", "合计", true, 10, ActKey.CENTER, ActKey.CENTER, true, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("goods_id", null, true, 0, null, null, false, false));
            this.dataGridView1.Columns.Add(GenearteDataGridViewColumn.GetDataGridViewDataFieldColumn("price_cost", null, true, 0, null, null, false, false));
        }

        #endregion

        #region 窗体控件事件

        /// <summary>
        /// 客户编号文本框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textbox_memberno_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((int)e.KeyChar == 13)
            {
                textBox_barcode.Focus();
                TextboxMemberHandler(true);
            }
        }

        /// <summary>
        /// 新增客户
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_memberadd_Click(object sender, EventArgs e)
        {
            this.CreateMember(textbox_memberno.Text.Trim());
        }

        /// <summary>
        /// 商品条码文本框键盘事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_barcode_KeyPress(object sender, KeyPressEventArgs e)
        {
            Control control = sender as Control;
            if (control != null)
            {
                int keyValue = (int)e.KeyChar;
                if (keyValue == 13)
                {
                    //添加出货单商品
                    if (control.Name.Equals(textBox_barcode.Name) && !String.IsNullOrEmpty(textBox_barcode.Text.Trim()))
                    {
                        this.AddShipmentGoods(textBox_barcode.Text.Trim());
                    }
                }
            }
        }

        /// <summary>
        /// 窗体关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PosForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool isclose = true;
            if (dataGridView1.Rows.Count > 0)
            {
                DialogResult result = MessageBox.Show("当前有未结算商品，确定要退出吗？", "提示", MessageBoxButtons.YesNo);
                if (result == DialogResult.No)
                {
                    e.Cancel = true;
                    isclose = false;
                }
            }
            if (isclose)
                posform = null;
        }

        /// <summary>
        /// 重写窗体快捷键事件
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            bool b = base.ProcessCmdKey(ref msg, keyData);
            switch (keyData)
            {
                case Keys.Add:
                    if (dataGridView1.Rows.Count > 0)
                    {
                        this.OpenPayForm();
                    }
                    b = true;
                    break;
                case Keys.Oemplus:
                    if (dataGridView1.Rows.Count > 0)
                    {
                        this.OpenPayForm();
                    }
                    b = true;
                    break;
                case Keys.F1:
                    this.PrinterSetting();
                    break;
                case Keys.F2: 
                    textbox_memberno.Focus();
                    break;
                case Keys.F3:
                    this.CreateMember(textbox_memberno.Text.Trim());
                    break;
                case Keys.F4: 
                    textBox_barcode.Focus();
                    break;
                case Keys.OemQuestion: 
                    textBox_numbers.Focus();
                    b = true;
                    break;
                case Keys.Divide: 
                    textBox_numbers.Focus();
                    b = true;
                    break;
                case Keys.Up: 
                    dataGridView1.Focus();
                    break;
                case Keys.Down: 
                    dataGridView1.Focus();
                    break;
                case Keys.Escape: 
                    this.Close();
                    break;
                case Keys.Delete:
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        DialogResult result = MessageBox.Show("确定要删除选中商品吗？", "提示", MessageBoxButtons.YesNo);
                        if (result == DialogResult.Yes)
                        {
                            dataGridView1.Rows.RemoveAt(dataGridView1.Rows[0].Index);
                            this.CountShipment();
                        }
                    }
                    break;
                case Keys.F5:
                    if (dataGridView1.Rows.Count > 0)
                    {
                        DialogResult result = MessageBox.Show("确定要删除所有商品吗？", "提示", MessageBoxButtons.YesNo);
                        if (result == DialogResult.Yes)
                        {
                            dataGridView1.Rows.Clear();
                            this.CountShipment();
                        }
                    }
                    break;
                case Keys.F6:
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        DiscountForm discountForm = new DiscountForm(this, this.shipmentTotal_first, this.discountType, this.discount, this.discountAmount);
                        discountForm.ShowDialog();
                    }
                    break;
                case Keys.F7:
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        String goodsname = dataGridView1.SelectedRows[0].Cells["goods_name"].Value.ToString();
                        int numbers = (int)dataGridView1.SelectedRows[0].Cells["numbers"].Value;
                        UpdateShipmentForm shipmentform = new UpdateShipmentForm(this, "numbers", goodsname, numbers);
                        shipmentform.ShowDialog();
                    }
                    break;
                case Keys.F8:
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        String goodsname = dataGridView1.SelectedRows[0].Cells["goods_name"].Value.ToString();
                        decimal price_sale = (decimal)dataGridView1.SelectedRows[0].Cells["price_sale"].Value;
                        UpdateShipmentForm shipmentform = new UpdateShipmentForm(this, "price_sale", goodsname, price_sale);
                        shipmentform.ShowDialog();
                    }
                    break;
                case Keys.F9:
                    if (dataGridView1.Rows.Count > 0)
                    {
                        DialogResult result = MessageBox.Show("确定要挂单吗？", "提示", MessageBoxButtons.YesNo);
                        if (result == DialogResult.Yes)
                        {
                            PayDataInfo payDataInfo = new PayDataInfo();
                            payDataInfo.ShipmentState = ShipmentState.PENDING;
                            payDataInfo.Payway = Payway.Cash;
                            this.ShipmentAccounts(payDataInfo);
                        }
                    }
                    break;
                case Keys.F10:
                    UnPendingForm unPendingForm = new UnPendingForm(this, shipmentTable);
                    unPendingForm.ShowDialog();
                    break;
                case Keys.F11:
                    this.PrintTickent();
                    break;
                case Keys.F12:
                    this.OpenMoneybox();
                    break;
            }
            return b;
        }

        /// <summary>
        /// 出货数量按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_numbers_KeyPress(object sender, KeyPressEventArgs e)
        {
            int keyValue = (int)e.KeyChar;
            if ((keyValue > 47 && keyValue < 58) || keyValue == 8)
                e.Handled = false;
            else if (keyValue == 13)
            {
                e.Handled = false;
                textBox_barcode.Focus();
            }
            else
                e.Handled = true;
        }

        /// <summary>
        /// 快捷键按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void shortcut_button_click(object sender, EventArgs e)
        {
            String shortcut = ((Button)sender).Text.Trim().ToLower();
            switch (shortcut)
            {
                case "+":
                    if (dataGridView1.Rows.Count > 0)
                    {
                        this.OpenPayForm();
                    }
                    break;
                case "/":
                    textBox_numbers.Focus();
                    break;
                case "del":
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        DialogResult result = MessageBox.Show("确定要删除选中商品吗？", "提示", MessageBoxButtons.YesNo);
                        if (result == DialogResult.Yes)
                        {
                            dataGridView1.Rows.RemoveAt(dataGridView1.Rows[0].Index);
                            this.CountShipment();
                        }
                    }
                    break;
                case "f1":
                    this.PrinterSetting();
                    break;
                case "f2":
                    textbox_memberno.Focus();
                    break;
                case "f3":
                    this.CreateMember(textbox_memberno.Text.Trim());
                    break;
                case "f4":
                    textBox_barcode.Focus();
                    break;               
                case "f5":
                    if (dataGridView1.Rows.Count > 0)
                    {
                        DialogResult result = MessageBox.Show("确定要删除所有商品吗？", "提示", MessageBoxButtons.YesNo);
                        if (result == DialogResult.Yes)
                        {
                            dataGridView1.Rows.Clear();
                            this.CountShipment();
                        }
                    }
                    break;
                case "f6":
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        DiscountForm discountForm = new DiscountForm(this, this.shipmentTotal_first, this.discountType, this.discount, this.discountAmount);
                        discountForm.ShowDialog();
                    }
                    break;
                case "f7":
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        String goodsname = dataGridView1.SelectedRows[0].Cells["goods_name"].Value.ToString();
                        int numbers = (int)dataGridView1.SelectedRows[0].Cells["numbers"].Value;
                        UpdateShipmentForm shipmentform = new UpdateShipmentForm(this, "numbers", goodsname, numbers);
                        shipmentform.ShowDialog();
                    }
                    break;
                case "f8":
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        String goodsname = dataGridView1.SelectedRows[0].Cells["goods_name"].Value.ToString();
                        decimal price_sale = (decimal)dataGridView1.SelectedRows[0].Cells["price_sale"].Value;
                        UpdateShipmentForm shipmentform = new UpdateShipmentForm(this, "price_sale", goodsname, price_sale);
                        shipmentform.ShowDialog();
                    }
                    break;
                case "f9":
                    if (dataGridView1.Rows.Count > 0)
                    {
                        DialogResult result = MessageBox.Show("确定要挂单吗？", "提示", MessageBoxButtons.YesNo);
                        if (result == DialogResult.Yes)
                        {
                            PayDataInfo payDataInfo = new PayDataInfo();
                            payDataInfo.ShipmentState = ShipmentState.PENDING;
                            payDataInfo.Payway = Payway.Cash;
                            this.ShipmentAccounts(payDataInfo);
                        }
                    }
                    break;
                case "f10":
                    UnPendingForm unPendingForm = new UnPendingForm(this, shipmentTable);
                    unPendingForm.ShowDialog();
                    break;
                case "f11":
                    this.PrintTickent();
                    break;
                case "f12":
                    this.OpenMoneybox();
                    break;
            }
        }

        /// <summary>
        /// 收银硬件设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_setting_Click(object sender, EventArgs e)
        {
            this.PrinterSetting();
        }

        #endregion

        #region 功能方法实现

        /// <summary>
        /// 会员编号输入框处理事件
        /// </summary>
        private void TextboxMemberHandler(bool isOpenMemberForm)
        {
            String memberno = textbox_memberno.Text.Trim();
            if (!String.IsNullOrEmpty(memberno))
            {
                member = memberService.GetMember(0, memberno);
                if (member == null)
                    member = memberService.GetMemberByMobile(memberno);
                if (member != null)
                {
                    if (member.IsLock)
                    {
                        MessageBox.Show("会员已锁定：" + member.LockReason);
                        textbox_memberno.Text = String.Empty;
                        return;
                    }
                    else
                    {
                        textbox_memberno.Text = member.Memberno;
                        textbox_membername.Text = member.Name;
                    }
                }
                else
                {
                    if (isOpenMemberForm)
                    {
                        this.CreateMember(memberno);
                    }
                }
            }
            else
                return;
        }

        /// <summary>
        /// 新增会员
        /// </summary>
        private void CreateMember(String memberno)
        {
            MemberAddForm memberAddForm = new MemberAddForm(mainform, this, memberno);
            memberAddForm.ShowDialog();
        }

        /// <summary>
        /// 打开支付窗口
        /// </summary>
        private void OpenPayForm()
        {
            PayForm payform = new PayForm(this, Decimal.Parse(label_totalnew.Text.Trim()), member);
            payform.ShowDialog();
        }

        /// <summary>
        /// 添加出货单商品
        /// </summary>
        /// <param name="barcode"></param>
        private void AddShipmentGoods(String barcode)
        {
            try
            {
                int reqStock = 0;
                if (!String.IsNullOrEmpty(textBox_numbers.Text.Trim()) && Regex.IsMatch(textBox_numbers.Text.Trim(), RegexExpress.NUMBER))
                {
                    reqStock = Int32.Parse(textBox_numbers.Text.Trim());
                }
                DataTable dt = goodsService.GetGoodsTable(0, 0, barcode, null, 0, 0, null, 0, "id", null);
                if (dt != null && dt.Rows.Count > 0)
                {
                    if (dt.Rows.Count > 1)
                    {
                        GoodsNormForm goodsNormForm = new GoodsNormForm(this, dt, "norm", "id");
                        goodsNormForm.ShowDialog();
                    }
                    else
                    {
                        String strStock = dt.Rows[0]["stock"].ToString();
                        int stock = Int32.Parse(strStock);
                        //int stock = (Int32)dt.Rows[0]["stock"];
                        if (stock >= reqStock)
                        {
                            this.DataGridViewAddRow(dt.Rows[0]);
                        }
                        else
                        {
                            MessageBox.Show("当前库存不足，剩余" + stock + "件！");
                        }
                    }
                }
                else
                {
                    MessageBox.Show("没有查询到此商品！");
                    textBox_barcode.Text = String.Empty;
                    textBox_numbers.Text = "1";
                    textBox_stock.Text = "0";
                }
            }
            catch (Exception ex)
            {
                LogsUtil.Record(ex);
            }
        }

        /// <summary>
        /// DataGridView添加行
        /// </summary>
        /// <param name="row"></param>
        public void DataGridViewAddRow(DataRow row)
        {
            try
            {
                bool isSameGoods = false;
                int rowIndex = 0;
                int numbers = 0;
                if (!String.IsNullOrEmpty(textBox_numbers.Text.Trim()))
                {
                    numbers = Convert.ToInt32(textBox_numbers.Text.Trim());
                }
                if (dataGridView1.Rows.Count > 0)
                {
                    long goodsId = Convert.ToInt64(row["id"]);
                    foreach (DataGridViewRow lopRow in dataGridView1.Rows)
                    {
                        if (goodsId == (long)lopRow.Cells["goods_id"].Value)
                        {
                            rowIndex = lopRow.Index;
                            numbers = Convert.ToInt32(lopRow.Cells["numbers"].Value) + numbers;
                            lopRow.Cells["numbers"].Value = numbers;
                            decimal price_disc = Convert.ToDecimal(lopRow.Cells["price_disc"].Value);
                            dataGridView1.Rows[rowIndex].Cells["total"].Value = price_disc * numbers;
                            isSameGoods = true;
                            break;
                        }
                    }
                }
                if (!isSameGoods)
                {
                    rowIndex = dataGridView1.Rows.Add();
                    dataGridView1.Rows[rowIndex].Cells["barcode"].Value = row["barcode"];
                    dataGridView1.Rows[rowIndex].Cells["goods_name"].Value = row["name"];
                    dataGridView1.Rows[rowIndex].Cells["category_name"].Value = row["categoryname"];
                    dataGridView1.Rows[rowIndex].Cells["goods_norm"].Value = row["norm"];
                    dataGridView1.Rows[rowIndex].Cells["price_sale"].Value = row["price_sale"];
                    dataGridView1.Rows[rowIndex].Cells["discount"].Value = row["discount"];
                    decimal price_cost = (decimal)row["price_cost"];
                    decimal price_sale = (decimal)row["price_sale"];
                    decimal discount = (decimal)row["discount"];
                    decimal price_disc = price_sale * discount;
                    dataGridView1.Rows[rowIndex].Cells["price_disc"].Value = price_disc;                   
                    dataGridView1.Rows[rowIndex].Cells["numbers"].Value = numbers;
                    dataGridView1.Rows[rowIndex].Cells["total"].Value = price_disc * numbers;
                    dataGridView1.Rows[rowIndex].Cells["goods_id"].Value = row["id"];
                    dataGridView1.Rows[rowIndex].Cells["price_cost"].Value = price_cost;
                }

                dataGridView1.Rows[rowIndex].Selected = true;
                textBox_stock.Text = (Convert.ToInt32(row["stock"].ToString()) - numbers).ToString();
                textBox_barcode.Text = String.Empty;
                textBox_numbers.Text = "1";

                this.CountShipment();
            }
            catch (Exception ex)
            {
                LogsUtil.Record(ex);
            }
        }

        /// <summary>
        /// 计算帐单
        /// </summary>
        public void CountShipment()
        {
            try
            {
                decimal total_old = 0M;
                decimal total_new = 0M;
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    total_old += (decimal)row.Cells["price_sale"].Value * (int)row.Cells["numbers"].Value;
                    total_new += Decimal.Parse(row.Cells["total"].Value.ToString());
                }
                label_totalold.Text = total_old.ToString("f2");
                label_totaldiscount.Text = (total_old - total_new).ToString("f2");
                label_totalnew.Text = total_new.ToString("f2");
                //最初订单金额
                this.shipmentTotal_first = total_new;
            }
            catch (Exception ex)
            {
                LogsUtil.Record(ex);
            }
        }

        /// <summary>
        /// 计算帐单优惠/回调
        /// </summary>
        /// <param name="discountType">优惠方式</param>
        /// <param name="discount">优惠数量</param>
        /// <param name="discountAmount">优惠金额</param>
        public void ShipmentDiscount(DiscountType discountType, decimal discount, decimal discountAmount)
        {
            try
            {
                if (discountAmount > 0)
                {
                    this.discountType = discountType;
                    this.discount = discount;
                    this.discountAmount = discountAmount;

                    decimal oldTotal = Decimal.Parse(label_totalold.Text);
                    decimal discountTotal = oldTotal - this.shipmentTotal_first + discountAmount;
                    label_totaldiscount.Text = discountTotal.ToString("f2");
                    label_totalnew.Text = (oldTotal - discountTotal).ToString("f2");
                }
            }
            catch (Exception ex)
            {
                LogsUtil.Record(ex);
            }
        }

        /// <summary>
        /// 修改表格数据
        /// </summary>
        /// <param name="columnname"></param>
        /// <param name="value"></param>
        public void UpdateDataGridViewCell(String columnname, Object value)
        {
            if (dataGridView1.SelectedRows.Count > 0)
            {
                dataGridView1.SelectedRows[0].Cells[columnname].Value = value;
                decimal price_disc = 0M;
                int numbers = 0;
                if (columnname.Equals("price_sale"))
                {
                    decimal price_sale = (decimal)value;
                    decimal discount = (decimal)dataGridView1.Rows[0].Cells["discount"].Value;
                    price_disc = price_sale * discount;
                    dataGridView1.Rows[0].Cells["price_disc"].Value = price_disc;
                    numbers = (int)dataGridView1.Rows[0].Cells["numbers"].Value;
                }
                else if (columnname.Equals("numbers"))
                {
                    price_disc = (decimal)dataGridView1.Rows[0].Cells["price_disc"].Value;
                    numbers = (int)value;                   
                }

                dataGridView1.SelectedRows[0].Cells["total"].Value = price_disc * numbers;
                this.CountShipment();
            }
        }

        /// <summary>
        /// 支付结算
        /// </summary>
        /// <param name="payDataInfo"></param>
        public void ShipmentAccounts(PayDataInfo payDataInfo)
        {
            try
            {
                BillShipment billShipment = new BillShipment();
                billShipment.EnterpriseNo = mainform.Admin.EnterpriseNo;
                billShipment.StoreNo = mainform.Admin.StoreNo;
                billShipment.Shipmentno = label_shipmentno.Text;
                billShipment.Memberno = textbox_memberno.Text.Trim();
                billShipment.Numbers = 0;
                billShipment.GoodsTotal = Decimal.Parse(label_totalold.Text);
                billShipment.ShipmentTotal = Decimal.Parse(label_totalnew.Text);
                billShipment.DiscountType = String.Empty;
                if (this.discountType == DiscountType.Discount)
                    billShipment.DiscountType = "打折";
                else if (this.discountType == DiscountType.Less)
                    billShipment.DiscountType = "直减";
                billShipment.DiscountAmount = this.discountAmount;
                billShipment.DiscountTotal = Decimal.Parse(label_totaldiscount.Text);
                billShipment.Payway = (int)payDataInfo.Payway;
                billShipment.MemberBalance = payDataInfo.UsedBalance;
                billShipment.IntegralAmount = payDataInfo.IntegralAmount;
                billShipment.PayIntegral = Config.EXCHANGEMONEY * (int)payDataInfo.IntegralAmount;
                billShipment.PayableAmount = payDataInfo.PayableAmount;
                billShipment.PayAmount = payDataInfo.PayAmount;
                billShipment.GiveAmount = payDataInfo.GiveAmount;
                decimal debtAmount = billShipment.ShipmentTotal - payDataInfo.UsedBalance - payDataInfo.IntegralAmount - (payDataInfo.PayAmount - payDataInfo.GiveAmount);
                if (debtAmount > 0)
                    billShipment.DebtAmount = debtAmount;
                billShipment.ShipmentDate = DateTime.Parse(textbox_shipmentdate.Text.Trim());
                billShipment.Note = String.Empty;
                billShipment.AdminUsername = mainform.Admin.Username;
                billShipment.AdminName = mainform.Admin.Name;
                billShipment.Createtime = DateTime.Now;

                int goodsNumbers = 0;
                ArrayList list = new ArrayList();
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    BillShipmentGoods shipmentGoods = new BillShipmentGoods();
                    shipmentGoods.EnterpriseNo = billShipment.EnterpriseNo;
                    shipmentGoods.StoreNo = billShipment.StoreNo;
                    shipmentGoods.Shipmentno = billShipment.Shipmentno;
                    shipmentGoods.GoodsId = (long)row.Cells["goods_id"].Value;
                    shipmentGoods.Barcode = row.Cells["barcode"].Value.ToString();
                    shipmentGoods.CategoryName = row.Cells["category_name"].Value.ToString();
                    shipmentGoods.GoodsName = row.Cells["goods_name"].Value.ToString();
                    shipmentGoods.GoodsNorm = row.Cells["goods_norm"].Value.ToString();
                    shipmentGoods.PriceCost = (decimal)row.Cells["price_cost"].Value;
                    shipmentGoods.PriceSale = (decimal)row.Cells["price_sale"].Value;
                    shipmentGoods.Discount = (decimal)row.Cells["discount"].Value;
                    shipmentGoods.PriceDisc = (decimal)row.Cells["price_disc"].Value;
                    shipmentGoods.Numbers = (int)row.Cells["numbers"].Value;
                    shipmentGoods.Total = (decimal)row.Cells["total"].Value;
                    shipmentGoods.Paid = shipmentGoods.Total;
                    shipmentGoods.Debt = 0M;
                    shipmentGoods.AdminUsername = billShipment.AdminUsername;
                    shipmentGoods.AdminName = billShipment.AdminName;
                    shipmentGoods.Createtime = DateTime.Now;

                    goodsNumbers += shipmentGoods.Numbers;
                    list.Add(shipmentGoods);
                }
                billShipment.Numbers = goodsNumbers;
                //保存
                if (payDataInfo.ShipmentState == ShipmentState.SAVE)
                {
                    if (this.discount > 0)
                        billShipment.DiscountType = billShipment.DiscountType + "/" + this.discount.ToString("f2");
                    else
                        billShipment.DiscountType = String.Empty;

                    //会员卡内余额
                    MemberMoney memberMoney = null;
                    if (payDataInfo.UsedBalance > 0)
                    {
                        memberMoney = new MemberMoney();
                        memberMoney.EnterpriseNo = billShipment.EnterpriseNo;
                        memberMoney.StoreNo = billShipment.StoreNo;
                        memberMoney.TransNo = billShipment.Shipmentno;
                        memberMoney.MemberNo = billShipment.Memberno;
                        memberMoney.Money = payDataInfo.UsedBalance;
                        memberMoney.LastMoney = member.Balance >= payDataInfo.UsedBalance ? (member.Balance - payDataInfo.UsedBalance) : 0;
                        memberMoney.MoneyTime = DateTime.Now;
                        memberMoney.Note = "出货单号：" + billShipment.Shipmentno;
                        memberMoney.AdminUsername = billShipment.AdminUsername;
                        memberMoney.AdminName = billShipment.AdminName;
                        memberMoney.CreateTime = DateTime.Now;
                    }
                    //保存出货单
                    long id = this.shipmentService.InsertBillShipment(billShipment, list, memberMoney);
                    if (id > 0)
                    {
                        //存入打印容器中
                        this.posBillPrintDoc = new PosBillPrintDoc(billShipment, list);
                        this.PrintPosBill(); //打印小票
                        this.RestorePosForm();
                    }
                }
                else if (payDataInfo.ShipmentState == ShipmentState.PENDING) //挂单
                {
                    if (this.discountAmount > 0)
                    {
                        //恢复优惠之前的原始数据
                        billShipment.ShipmentTotal = this.shipmentTotal_first;
                        billShipment.DiscountType = String.Empty;
                        billShipment.DiscountAmount = 0M;
                        billShipment.DiscountTotal = billShipment.GoodsTotal - this.shipmentTotal_first;
                        //清空优惠方案
                        this.discountType = DiscountType.Discount;
                        this.discount = 0M;
                        this.discountAmount = 0M;
                    }
                    this.Pending(billShipment, list);
                }
            }
            catch (Exception ex)
            {
                LogsUtil.Record(ex);
            }
        }

        /// <summary>
        /// 挂单
        /// </summary>
        /// <param name="billShipment"></param>
        /// <param name="list"></param>
        protected void Pending(BillShipment billShipment, ArrayList list)
        {
            shipmentTable.Add(billShipment, list);
            this.RestorePosForm();
        }

        /// <summary>
        /// 解挂
        /// </summary>
        /// <param name="shipmentno"></param>
        public void UnPending(String shipmentno)
        {
            if (shipmentTable != null && shipmentTable.Count > 0)
            {
                IEnumerator iter = shipmentTable.Keys.GetEnumerator();
                while (iter.MoveNext())
                {
                    BillShipment lopBillShipment = iter.Current as BillShipment;
                    if (lopBillShipment.Shipmentno.Equals(shipmentno))
                    {
                        textbox_memberno.Text = lopBillShipment.Memberno;
                        textbox_shipmentuser.Text = lopBillShipment.AdminName;
                        textbox_shipmentdate.Text = lopBillShipment.ShipmentDate.ToString("yyyy-MM-dd");
                        label_shipmentno.Text = lopBillShipment.Shipmentno;
                        label_totalold.Text = lopBillShipment.GoodsTotal.ToString("f2");
                        label_totalnew.Text = lopBillShipment.ShipmentTotal.ToString("f2");
                        label_totaldiscount.Text = lopBillShipment.DiscountTotal.ToString("f2");
                        if (String.IsNullOrEmpty(lopBillShipment.DiscountType))
                            this.discountType = DiscountType.NO;
                        else if (lopBillShipment.DiscountType.Equals("打折"))
                            this.discountType = DiscountType.Discount;
                        else if (lopBillShipment.DiscountType.Equals("直减"))
                            this.discountType = DiscountType.Less;
                        this.discountAmount = lopBillShipment.DiscountAmount;

                        ArrayList list = shipmentTable[lopBillShipment] as ArrayList;
                        foreach (BillShipmentGoods shipmentGoods in list)
                        {
                            int rowIndex = dataGridView1.Rows.Add();
                            dataGridView1.Rows[rowIndex].Cells["goods_id"].Value = shipmentGoods.GoodsId;
                            dataGridView1.Rows[rowIndex].Cells["barcode"].Value = shipmentGoods.Barcode;
                            dataGridView1.Rows[rowIndex].Cells["category_name"].Value = shipmentGoods.CategoryName;
                            dataGridView1.Rows[rowIndex].Cells["goods_name"].Value = shipmentGoods.GoodsName;
                            dataGridView1.Rows[rowIndex].Cells["goods_norm"].Value = shipmentGoods.GoodsNorm;
                            dataGridView1.Rows[rowIndex].Cells["price_cost"].Value = shipmentGoods.PriceCost;
                            dataGridView1.Rows[rowIndex].Cells["price_sale"].Value = shipmentGoods.PriceSale;
                            dataGridView1.Rows[rowIndex].Cells["discount"].Value = shipmentGoods.Discount;
                            dataGridView1.Rows[rowIndex].Cells["price_disc"].Value = shipmentGoods.PriceDisc;
                            dataGridView1.Rows[rowIndex].Cells["numbers"].Value = shipmentGoods.Numbers;
                            dataGridView1.Rows[rowIndex].Cells["total"].Value = shipmentGoods.Total;
                        }
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 打开钱箱
        /// </summary>
        private void OpenMoneybox()
        {
            String printerName = printDocument1.PrinterSettings.PrinterName;
            //标准 
            //String send = "" + (char)(27) + (char)(64) + (char)(27) + 'J' + (char)(255);   
            //非标准   
            String send = "" + (char)(27) + (char)(112) + (char)(0) + (char)(60) + (char)(255);
            RawPrinterHelper.SendStringToPrinter(printerName, send);
        }

        /// <summary>
        /// 打印POS出货小票
        /// </summary>
        private void PrintPosBill()
        {
            if (printDocument1.PrinterSettings.IsValid && ToolsUtil.IsReadyWithPrinter(printDocument1.PrinterSettings.PrinterName))
            {
                if (Config.TICKET_PRINT_PREVIEW)
                {
                    printPreviewDialog1.PrintPreviewControl.Zoom = 1;
                    printPreviewDialog1.ShowDialog();
                }
                else
                {
                    System.Threading.Thread thread = new System.Threading.Thread(LanuchPrintr);
                    thread.Start();
                }
            }
        }

        /// <summary>
        /// 启动打印
        /// </summary>
        private void LanuchPrintr()
        {
            this.OpenMoneybox();
            printDocument1.Print();
        }

        /// <summary>
        /// 补打小票
        /// </summary>
        private void PrintTickent()
        {
            PrintTicketForm printTicket = new PrintTicketForm(mainform);
            printTicket.ShowDialog();
        }

        /// <summary>
        /// 打印设置
        /// </summary>
        private void PrinterSetting()
        {
            PrinterSettingForm printerSettingForm = new PrinterSettingForm(this.mainform, printDocument1.PrinterSettings);
            printerSettingForm.ShowDialog();
        }

        #endregion

        #region IGoodsNorm 成员

        void IGoodsNorm.SelectGoodsNorm(object param)
        {
            if (param != null)
            {
                int reqStock = Int32.Parse(textBox_numbers.Text.Trim());
                DataRow row = (DataRow)param;
                int stock = (int)row["stock"];
                if (stock >= reqStock)
                {
                    this.DataGridViewAddRow(row);
                }
                else
                {
                    MessageBox.Show("当前库存不足，剩余" + stock + "件！");
                }
            }
        }

        #endregion


        #region IReloadData 成员

        void IReloadData.ReloadDataGridViewData(object param)
        {
            if (param != null)
            {
                textbox_memberno.Text = param.ToString();
                this.TextboxMemberHandler(false);
            }
            else
                textbox_memberno.Text = String.Empty;
            textBox_barcode.Focus();
        }

        #endregion

        #region 打印控件事件

        /// <summary>
        /// 打印POS小票事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            if (this.posBillPrintDoc!=null)
            {
                this.posBillPrintDoc.Print(label_shipmentno.Text, mainform.Admin.Name + "  " + mainform.Admin.Mobile, e);
            }
        }

        #endregion

    }
}
